'use strict';

//引用外源库，实现快捷键绑定
var Mousetrap = require('mousetrap');

//用于保存功能按键的选择 1：画笔 2：橡皮 3：线条 4.矩形
let choice = 0;
//按钮数组，用于保存一系列ID名，用于确定已初始化的按钮
let btnArray = {};
//指针状态数组，用于保存指针的状态
let cursorArray = {};
//历史序列，用于保存历史操作的快照数据
let historyArray = new Array();
//历史快照的总数限制
let historyLength = 100;
//当前快照在历史序列中的位置
let lstep = -1;
let cstep = -1;
//画布笔触跟踪判定
let retracing = false;
let clickedTools = {'shape':'', 'effect':''};
let lastText = "";

//设置常数参量
let inputHeight = 430;
let inputWidth = 990;

let delInfo = {'id': null, 'prepare': false}
let lastNull = null;

//主函数入口
$(function(){
	//chocie ->> 1: pencil 2:earser 3:line 4:rect

	let x,y,endX,endY;
	let mouseDown = false;

	let borderWidth = 1;
	historyPush("image");

	//临时线条，用于在绘制线条过程中给用户预览
	let fakeLineCss = analayzeLine({
		"beginX": 0,
		"beginY": 0,
		"endX": 1,
		"endY": 1,
	});
	let fakeLine = $("<div></div>");
	fakeLine.css({
		"position": "absolute",
		"transform": fakeLineCss.transform,
		"border-top": "1px solid #fff",
		"left": fakeLineCss.left,
		"top": fakeLineCss.top,
		"width": fakeLineCss.width
	});

	$("#paintArea").append(fakeLine);

	//临时矩形，用于在绘制矩形时给用户预览
	let fakeRect = $("<div style='position:absolute;border:1px solid #000;left: 1px;top: 1px;display:none;z-index:20;'></div>");
	$("#paintArea").append(fakeRect);

	//初始化四个绘图按键
	processBtn("pencil", 1);
	processBtn("eraser", 2);
	processBtn('line', 3);
	processBtn("rect", 4);

	//监听鼠标移动事件，更新坐标点
	$('#paintArea').mousedown(function(e){
		mouseDown = true;
		let offset = $(this).offset();
		x = e.pageX - offset.left;
		y = e.pageY - offset.top;
		if(choice == 3)
		{
			fakeLine.show();
		}
		else if(choice == 4)
		{
			fakeRect.show();
		}
	});

	//结束位移后，显示绘制结果
	$('#paintArea').mouseup(function(){
		mouseDown = false;
		let ctx = $("#painter")[0].getContext('2d');
		if(choice == 3)
		{
			ctx.beginPath();
			ctx.moveTo(x,y);
			ctx.lineTo(endX,endY);
			ctx.stroke();
			fakeLine.hide();
		}
		else if(choice == 4)
		{
			ctx.strokeRect(x,y,endX-x-2*borderWidth,endY-y-2*borderWidth);
			fakeRect.hide();
		}
		if(choice != 0)
			historyPush('image');
	});

	//实时更新坐标
	$("#paintArea").mousemove(function(e){
		let offset = $("#painter").offset();
		let ctx = $("#painter")[0].getContext('2d');

		endX = e.pageX - offset.left;
		endY = e.pageY - offset.top;

		if(choice != 2)
		{
			ctx.strokeStyle = '#000';
			ctx.lineWidth = 1;
		}
		else
		{
			ctx.strokeStyle = '#fff';
			ctx.lineWidth = 15;
		}

		if(choice < 3 && choice > 0)
		{
			if(mouseDown)
			{
				ctx.lineTo(endX, endY);
				ctx.stroke();
			}
			else
			{
				ctx.beginPath();
				ctx.moveTo(endX, endY);
			}
		}
		else if(choice == 3)
		{
			if(mouseDown)
			{
				let tempCss = analayzeLine({
					"beginX": x,
					"beginY": y,
					"endX": endX,
					"endY": endY
				});
				fakeLine.css({
					"transform": tempCss.transform,
					"left": tempCss.left,
					"top": tempCss.top,
					"z-index": 100,
					"width": tempCss.width
				});
			}
		}
		else if(choice == 4)
		{
			if(mouseDown)
			{
				fakeRect.css({
					'left': Math.min(x, endX),
					'top': Math.min(y,endY),
					'width': Math.abs(endX-x-borderWidth*2),
					'height': Math.abs(endY-y-borderWidth*2)
				});
			}
		}

	});

	//item_0初始化
	initItem('item_0');


	//快捷键设置
	//禁用默认ctrl+z
	$(document).keydown(function(e){
		if(e.ctrlKey && e.keyCode==90)
		{
			e.preventDefault();
		}
	});

	//绑定输入事件
	$("#titleInput").bind('input propertychange', ()=>{historyPush('title');});
	$("#contentInput").bind('input propertychange', ()=>{historyPush('text');});

	//快捷键绑定
	//Mousetrap.bind('ctrl+p', ()=>{$("#pencil").trigger('click');});
	//Mousetrap.bind('ctrl+e', ()=>{$("#eraser").trigger('click');});
	//Mousetrap.bind('ctrl+l', ()=>{$("#line").trigger('click');});
	//Mousetrap.bind('ctrl+r', ()=>{$("#rect").trigger('click');});
	Mousetrap.bind('ctrl+z', ()=>{
		applyHistory(lstep);
	});

	$("#brush").click(()=>clearCanvas());

	$("#previousBtn span").click(()=>{
		if(cstep > 0)
		{
			applyHistory(cstep - 1);
		}
	});

	$("#nextBtn span").click(()=>{
		if(cstep < historyArray.length - 1)
		{
			applyHistory(cstep + 1);
		}
	});
});

//绘制临时线条的css属性
//appendInfo = {beginX:,beginY:,endX:,endY:,type:(solid,dashed,etc),color:,width:(length)}
function analayzeLine(appendInfo)
{
	let x,y,arc,degree,length;
	//利用三角函数构造
	let width = appendInfo.endX - appendInfo.beginX;
	let height = appendInfo.endY - appendInfo.beginY;
	let atan = Math.abs(height/width);
	arc = Math.atan(atan);
	length = Math.sqrt(Math.pow(width, 2) + Math.pow(height, 2));

	let angle = (arc/Math.PI)*180;
	if(width>0 && height>0)
	{
		y = (length *Math.sin(arc))/2;
		x = -(length  - length*Math.cos(arc))/2;
		degree = angle;
	}
	else if(width<0 && height>0)
	{
		x = -(length + length*Math.cos(arc))/2;
		y = (length *Math.sin(arc))/2;
		degree = 180-angle;
	}
	else if(width <0 && height <0)
	{
		x = -(length + length*Math.cos(arc))/2;
		y = -(length *Math.sin(arc))/2;
		degree = 180+angle;
	}
	else if(width >0 && height <0)
	{
		x = -(length - length*Math.cos(arc))/2;
		y = -(length *Math.sin(arc))/2;
		degree = -angle;
	}

	let result = {
		transform: "rotate(" + degree + "deg)",
		width: length,
		left: appendInfo.beginX + x,
		top: appendInfo.beginY + y
	}
	return result;
}

//为按键添加事件监听器
function processBtn(id, choiceVal)
{
	let ctx = $("#painter")[0].getContext('2d');
	$('#' + id).click(function(){

		if(choice != choiceVal || retracing)
		{
			$(this).addClass('tool_clicked');
			$(this).removeClass('tool_unclicked');
			$("#contentInput").css({'z-index': '5'});
			$("#contentInput").attr('contenteditable', 'false');
			$("#painter").css({'z-index': '6'});
			choice = choiceVal;

			for(let item in btnArray)
			{
				if(item != id)
				{
					btnArray[item].removeClass('tool_clicked');
					btnArray[item].addClass('tool_unclicked');
				}
				if($("#painter").hasClass(item + "_cursor"))
				{
					$("#painter").removeClass(item + "_cursor");
				}
			}
			$("#painter").addClass(id + "_cursor");

			clickedTools.shape = id;
		}
		else if(choice == choiceVal)
		{
			$(this).removeClass('tool_clicked');
			$(this).addClass('tool_unclicked');
			$("#contentInput").css({'z-index': '6'});
			$("#contentInput").attr('contenteditable', 'true');
			$("#painter").css({'z-index': '5'});

			choice = 0;
			$("#painter").removeClass(id + "_cursor");
		}
		if(!retracing)
			historyPush('tool');
	});
	btnArray[id] = $('#' + id);
}


//副本存储
//type:image data:dataURL
//type:text data:document-undo
//type:tool data:btn-name
function historyPush(type)
{
	let ctx = $("#painter")[0].getContext('2d');

	toggleItem(cstep);
	lstep = cstep;
	cstep++;
	let labelVal = '';
	switch(type)
	{
		case 'tool': 
			switch(choice)
			{
				case 0: labelVal = '关闭画板';break;
				case 1: labelVal = '启动画笔';break;
				case 2: labelVal = '启动橡皮擦';break;
				case 3: labelVal = '启动直线工具';break;
				case 4: labelVal = '启动矩形工具';break;
			}
			break;
		case 'text': labelVal = '输入文字';break;
		case 'title': labelVal = '修改标题';break;
		case 'image': labelVal = '绘图';break;
		case 'clear': labelVal = '清空画布';break;
	}
	if(cstep < historyArray.length)
	{
		for(let i = cstep; i < historyArray.length; i++)
		{
			$("#item_" + i).remove();
		}
		//bug fix:修复回撤后无法正常写入新的历史记录的问题
		historyArray.splice(cstep, historyLength-cstep);
	}
	if(historyArray.length == historyLength)
	{
		lstep--;
		cstep--;
		removeItem(1);
	}
	

	historyArray.push({'type':type, 'text':$("#contentInput").html(), 'image': $("#painter").get(0).toDataURL(), 'button':collectState(), 'title':$("#titleInput").val()});

	if(cstep > 0)
	{
		let newItem = $("#item_0").clone();
		let id = 'item_' + cstep;
		newItem.attr('id', id);
		newItem.find('.historyText span').html(labelVal);
		//newItem.css({'top':(40+cstep*35) + 'px'});
		newItem.addClass('item_current');
		//newItem.removeClass('item_else');
		$("#historyList").append(newItem);
		initItem(id);
	}
}

//清除指定元素
function removeItem(start)
{
	historyArray.splice(start,1);
	$("#item_" + start).remove();
	for(let i = start; i < historyArray.length; i++)
	{
		let id = "item_" + i;
		let item = $("#historyList").find('li').get(i);
		item.setAttribute('id', id);
		initItem(id);
	}
}

//转变历史记录按键的状态
function toggleItem(step)
{
	if(lastNull)
	{
		$("#item_" + lastNull).removeClass('item_current');
	}
	let item = $("#item_" + step);
	if(item.hasClass('item_current'))
	{
		item.removeClass('item_current');
		//item.addClass('item_else');
	}
	else
	{
		//item.removeClass('item_else');
		item.addClass('item_current');
	}
}

//执行跳转
function applyHistory(step)
{
	//console.log(historyArray);
	let ctx = $("#painter")[0].getContext('2d');
	toggleItem(cstep);
	if(step >= 0)
	{
		let data = historyArray[step];
		let image = new Image();
		let btnState = data.button;

		choice = btnState.click.choice;


		if(data.type=='tool')
		{
			retracing = true;
			$('#' + data.button.click.shape).trigger('click');
			retracing = false;
		}

		if(choice == 0)
		{
			$("#contentInput").css({'z-index': '6'});
			$("#painter").css({'z-index': '5'});
			$("#contentInput").attr('contenteditable', 'true');
		}

		//bug fix :无法正常重置画布 新问题:画笔失效 重设choice解决
		ctx.clearRect(0,0,inputWidth,inputHeight);
		image.src = data.image;
		image.onload = function(){ctx.drawImage(image, 0, 0);}

		$("#contentInput").html(data.text);
		$("#titleInput").val(data.title);



		$("#colorSetting").val(btnState.color);
		$("#fontsizeSetting").val(btnState.size);
		$("#fontstyleSetting").val(btnState.type);

		let shapeId = btnState.click.shape;

		for(let item in btnArray)
		{
			if(item != shapeId)
			{
				btnArray[item].removeClass('tool_clicked');
				btnArray[item].addClass('tool_unclicked');
			}
			if($("#painter").hasClass(item + "_cursor"))
			{
				$("#painter").removeClass(item + "_cursor");
			}
		}
		$("#painter").addClass(shapeId + "_cursor");
	}

	lstep = cstep;
	cstep = step;
	toggleItem(cstep);
}

//采集当前的各个量状态值
function collectState()
{
	let fontSize = $("#fontsizeSetting").val();
	let fontType = $("#fontstyleSetting").val();
	let color = $("#colorSetting").val();

	return {'size':fontSize, 'type':fontType, 'color':color, 'click':{'shape':clickedTools.shape, 'effect':clickedTools.effect, 'choice':choice}};
}

//初始化各按键
function initItem(id)
{
	let ctx = $("#painter")[0].getContext('2d');
	let step = parseInt(id.split('_')[1]);
	$('#' + id).find('.historyType span:eq(0)').click(function(){
		let step = parseInt(id.split('_')[1]);
		applyHistory(step);
	});

	//???
	let delIcon = $('#' + id).find('.historyDel span:eq(0)');
	let confirmIcon = delIcon.next();
	let cancelIcon = delIcon.next().next();
	
	if(step != 0)
	{
		delIcon.click(function(){
			$(this).parent().prev().hide();
			$(this).parent().css({'width':'80%'});
			confirmIcon.show().text('确定删除本记录?');
			cancelIcon.show().attr('class', 'iconfont icon-close');
			delInfo['id'] = id;
			delInfo['prepare'] = true;
		});

		confirmIcon.click(function(){
			let currentID = delInfo['id']
			if(id == currentID && delInfo['prepare'])
			{
				for(let i = historyArray.length - 1; i > step - 1; i--)
				{
					$('#item_' + i).remove();
				}
				historyArray.splice(step, historyArray.length - step);
				if(cstep > step)
				{
					$("#item_" + (step-1)).addClass('item_current');
					lastNull = step-1;
				}
			}
		});

		cancelIcon.click(function(){
			$(this).parent().prev().show();
			$(this).parent().css({'width': '10%'});
			delInfo['id'] = null;
			delInfo['prepare'] = false;
			cancelIcon.hide();
			confirmIcon.hide();
		});
	}
	
}

//清空画布
function clearCanvas()
{
	$("#painter")[0].height = $("#painter")[0].height;
	historyPush('clear');
}

//重绘画布
function repaintCanvas(height, width=null, scale=false)
{
	let ctx = $("#painter")[0].getContext('2d');
	let currentImage = $("#painter")[0].toDataURL();
	let beforeHeight = $("#painter")[0].height;
	let beforeWidth = $("#painter")[0].width;

	$("#painter")[0].height = height;
	if(width)
	{
		$("#painter")[0].width = width;
	}
	let image = new Image();
	image.src = currentImage;
	image.onload = function(){
		ctx.save();
		if(width && scale)
		{
			ctx.scale(width/beforeWidth, height/beforeHeight);
		}
		ctx.drawImage(image, 0, 0);
		ctx.restore();
	}
}

function toggleTool(enableText=false)
{
	if(enableText)
	{
		$("#contentInput").css({'z-index': '6'});
		$("#contentInput").attr('contenteditable', 'true');
		$("#painter").css({'z-index': '5'});
	}
	else
	{
		$("#contentInput").css({'z-index': '5'});
		$("#contentInput").attr('contenteditable', 'false');
		$("#painter").css({'z-index': '6'});
	}
}
